/**
 * <p>文件名:		StringUtils.java</p>
 * <p>版权:		CopyrightTag</p>
 * <p>公司:		CompanyTag</p>
 * @author		周华彬(zhouhuabin@ctfo.com)
 */

package com.caits.lbs.framework.utils;

import java.io.UnsupportedEncodingException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;

import com.caits.lbs.framework.bean.common.BlurObject;
import com.caits.lbs.framework.log.CommonLogFactory;

/**
 * <p>
 * StringUtils
 * </p>
 * <p>
 * 字符串类通用工具类
 * </p>
 * 
 * @author 周华彬(zhouhuabin@ctfo.com)
 * @version 0.0.0
 *          <table style="border:1px solid gray;">
 *          <tr>
 *          <th width="100px">版本号</th>
 *          <th width="100px">动作</th>
 *          <th * width="100px">修改人</th>
 *          <th width="100px">修改时间</th>
 *          </tr>
 *          <!-- 以 Table 方式书写修改历史 -->
 *          <tr>
 *          <td>0.0.0</td>
 *          <td>创建类</td>
 *          <td>周华彬</td>
 *          <td>2008-7-11 下午05:00:41</td>
 *          </tr>
 *          <tr>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          </tr>
 *          </table>
 */
public class StringUtils {

	protected static Logger log = CommonLogFactory.getLog();
	/**
	 * 构造器
	 */
	private StringUtils() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * 判断输入字符串是否满足以下非空条件：<br>
	 * 不为空，剪头去尾后长度大于0，不论大小写字符串都不等于null
	 * 
	 * @param str
	 *            输入要判断的串
	 * @return 根据依据判断出的布尔结果
	 */
	public static boolean isNullOrBlank(String str) {
		if (str == null) {
			return true;
		}
		if (str.trim().length() <= 0) {
			return true;
		}
		if (str.equalsIgnoreCase("null")) {
			return true;
		}
		return false;
	}

	/**
	 * 非null而且内容不为空
	 * 
	 * @param str
	 * @return
	 */
	public static boolean notNullOrBlank(String str) {
		return !isNullOrBlank(str);
	}

	/**
	 * 安全的trim方式，剪头去尾，在输入为空的情况下也能安全剪除字符串两端的空白
	 * 
	 * @param str
	 * @return 返回绝不为空，至少为长度为0的串
	 */
	public static String trim(String str) {
		if (str == null) {
			return "";
		}
		return str.trim();
	}

	/**
	 * 获得字符串的数组表示
	 * 
	 * @param srcStr
	 *            使用(delim)符号分割的字符串
	 * @param delim
	 *            分割符，如果符号不是打印符号，则使用空格替代
	 * @param zeroSize
	 *            决定当拆不出任何数组的时候，是返回null还是零长度的对象，如果为true则返回0长度对象，否则直接null
	 * @return
	 */
	public static String[] splitToArray(String srcStr, String delim,
			boolean zeroSize) {
		String[] strArray = null;
		if (!isNullOrBlank(srcStr)) {
			// 如果分割符不是特殊符号，则默认使用空格分割
			if (isNullOrBlank(delim)) {
				delim = " ";
			}
			StringTokenizer stringTokenizer = new StringTokenizer(srcStr, delim);
			strArray = new String[stringTokenizer.countTokens()];
			for (int i = 0; stringTokenizer.hasMoreTokens(); i++) {
				strArray[i] = stringTokenizer.nextToken();
			}
		}
		if (zeroSize && strArray == null) {
			// 为了节省空间，需要指定长度为0
			strArray = new String[0];
		}
		return strArray;
	}

	/**
	 * 根据属性名找到对应列名的值，忽略大小写
	 * 
	 * @param name
	 *            名称
	 * @param row
	 *            数组
	 * @param labelList
	 *            对应的列数组
	 * @return BlurObject
	 */
	public static BlurObject getValeByName(String name, String[] row,
			String[] labelList) {
		String value = null;
		boolean finded = false;
		if (labelList.length != row.length)
			return null;
		for (int i = 0; i < labelList.length; i++) {
			String label = labelList[i];
			if (label.equalsIgnoreCase(name)) {
				value = row[i];
				finded = true;
				break;
			}
		}
		if (!finded) {
			return null;
		}
		return new BlurObject(value);
	}

	/**
	 * null convert to blank
	 * 
	 * @param string
	 * @return
	 */
	public static String null2blank(String string) {
		return string == null ? "" : string;
	}

	/**
	 * null convert to default string <br>
	 * the expression is
	 * <code>return string == null ? defaultVal : string</code>
	 * 
	 * @param string
	 *            to be checked string
	 * @param defaultVal
	 *            if string is null,will return defaultVal
	 * @return string or defaultVal
	 */
	public static String null2default(String string, String defaultVal) {
		return string == null ? defaultVal : string;
	}

	/**
	 * FIXME
	 * 
	 * @param src
	 * @return
	 */
	public static String removeSpace(String src) {
		if (src == null) {
			return "";
		}
		char[] ss = src.toCharArray();
		int j = 0;
		for (int i = 0; i < ss.length; i++) {
			if (ss[i] != ' ') {
				ss[j++] = ss[i];
			}
		}
		return new String(ss).substring(0, j);
	}

	/**
	 * FIXME
	 * 
	 * @param e
	 * @param l
	 * @return 决不返回空
	 */
	public static List<String> stacks(Throwable e, List<String> l) {
		if (e == null) {
			return new LinkedList<String>();
		}
		if (l == null) {
			l = new LinkedList<String>();
		}

		l.add(e.getMessage());
		StackTraceElement[] sts = e.getStackTrace();
		if (sts != null && sts.length > 0) {
			for (StackTraceElement s : sts) {
				l.add(s.toString());
			}
		}
		Throwable cause = e.getCause();
		if (cause != null) {
			stacks(cause, l);
		}
		return l;
	}
	/**
	 * 合并数组到字符串 
	 * @param arr
	 * @param sep 分割符
	 * @return
	 */
	public static String joinArrays(final String[] arr, String sep) {
		if(arr==null||arr.length<1)return "";
		StringBuilder sb = new StringBuilder(arr[0]);
		for(int i=1;i<arr.length;i++){
			String str = arr[i];
			sb.append(sep+str);
		}
		return sb.toString();
	}

	/**
	 * 
	 * 将map各元素追加到字符串后
	 * 
	 * @param builder
	 * @param map
	 * @return
	 */
	public static StringBuilder map2String(StringBuilder builder,
			String mapName, Map<?, ?> map) {
		if (map != null && !map.isEmpty()) {
			builder.append(mapName + ": {");
			for (Object key : map.keySet()) {
				builder.append(key);
				builder.append(':');
				builder.append(map.get(key));
				builder.append(", \r\n");
			}
			builder.append("}");
		} else {
			builder.append(mapName + ": ");
			builder.append(map);
		}
		return builder;
	}

	/**
	 * 
	 * 将列表各元素追加到字符串后
	 * 
	 * @param builder	被追加的地方
	 * @param listName	列表名称
	 * @param list		列表
	 * @return
	 */
	public static StringBuilder list2String(StringBuilder builder,
			String listName, List<?> list) {
		if (list != null && !list.isEmpty()) {
			builder.append(listName + ": (");
			for (Object value : list) {
				builder.append(value);
				builder.append(", ");
			}
			builder.append(")");
		} else {
			builder.append(listName + ": ");
			builder.append(list);
		}
		return builder;
	}

	/**
	 * 
	 * 将集合各元素追加到字符串后
	 * 
	 * @param builder
	 * @param setName
	 * @param set
	 * @return
	 */
	public static StringBuilder set2String(StringBuilder builder,
			String setName, Set<?> set) {
		if (set != null && !set.isEmpty()) {
			builder.append(setName + ": [");
			for (Object value : set) {
				builder.append(value);
				builder.append(", ");
			}
			builder.append("]");
		} else {
			builder.append(setName + ": ");
			builder.append(set);
		}
		return builder;
	}

	/**
	 * 取出某个字符串{}中的内容
	 * 
	 * @param string
	 * @return
	 */
	public static String takeOutString(String string) {
		if (string.indexOf('{') == -1) {
			return "";
		}

		string = string.substring(1);
		string = string.substring(0, string.length() - 1);

		if (StringUtils.notNullOrBlank(string)) {
			string = string + ", ";
		}
		return string;
	}

	/**
	 * 从数组里查找指定的属性是否存在
	 * 
	 * @param attributeName
	 * @param attributes
	 * @return
	 */
	public static boolean findAttributes(String attributeName,
			String[] attributes) {
		if (attributes == null || attributeName == null)
			return false;
		for (String attribute : attributes) {
			if (attributeName.equalsIgnoreCase(attribute))
				return true;
		}
		return false;
	}

	/**
	 * 将A编码字符串转换成B编码字符串
	 * 
	 * @param str
	 *            要转换的字符串
	 * @param sourceEncoding
	 *            原始编码
	 * @param destEncoding
	 *            目标编码
	 * @return 转换后的字符串
	 */
	public static String encodeConvert(String str, String sourceEncoding,
			String destEncoding) {
		if (str != null && sourceEncoding != null && destEncoding != null) {

			try {
				if (sourceEncoding.equalsIgnoreCase(destEncoding))
					return str;
				return new String(str.getBytes(sourceEncoding), destEncoding);
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return "";
	}

	/**
	 * 字节数组转换成指定编码的字符串 
	 * @param bytes	原始字节数组
	 * @param skip	开始位置
	 * @param charsetName	目标编码
	 * @return	字符串
	 * @throws UnsupportedEncodingException
	 */
	public static String getString(byte[] bytes, int skip, String charsetName)
			throws UnsupportedEncodingException {
		int start = skip;
		for (int i = 0; i < bytes.length - 1; i++) {
			if (bytes[i] < 0) {
				int sum = ((bytes[i] & 0xff) << 8) + (bytes[i + 1] & 0xff);
				if (sum >= 0x8140 && sum <= 0xFEFE) {
					if (++i == start) {
						start++; // 位置正好占半个汉字, 多跳过一个, 如果写成start--, 则表示少跳过一个
					}
				}
			}
			if (i >= start) {
				break;
			}
		}
		return new String(bytes, start, bytes.length - start, charsetName);
	}
	/**
	   * 将字符串s转化为html代码
	   * @param s 要转化的字符串
	   * @return 转化之后的字符串
	   */
	  public static String toHtml(String s) {
	    s = s.replace("&", "&amp;");
	    s = s.replace("<", "&lt;");
	    s = s.replace(">", "&gt;");
	    s = s.replace("\t", "    ");
	    s = s.replace("\r\n", "\n");
	    s = s.replace("\n", "<br>");
	    s = s.replace(" ", "&nbsp;");
	    s = s.replace("'", "&#39;");
	    s = s.replace("\\", "&#92;");
	    return s;
	  }
	  
	  /**
	 * 将html代码转化为 显示字符串s
	 * @param s
	 * @return
	 */
	public static String htmlTo(String s){
		    s = s.replace("&amp;", "&");
		    s = s.replace("&lt;", "<");
		    s = s.replace("&gt;", ">");
		    s = s.replace("    ", "\t");
		    s = s.replace("\n", "\r\n");
		    s = s.replace("<br>", "\n");
		    s = s.replace("&nbsp;", " ");
		    s = s.replace("&#39;", "'");
		    s = s.replace("&#92;", "\\");
		    return s;
		  }
	/**
	 * FIXME
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		List<String> l = stacks(
				new Exception("1234", new Exception("fe", null)), null);
		for (String r : l) {
			System.out.println(r);
		}
		try {

				String s = "A中华人民共和国B"; 
				byte[] bs = s.getBytes("UTF-8");  
				 for (int start = 0; start < bs.length; start++) {  
					     System.out.println("start: " + start + ",  value:" + getString(bs, start, "UTF-8"));  
//					     System.out.println("gbk2utf8转换后是:" + getString(line.getBytes("GBK"),0, "UTF-8"));
				}
		} catch (Exception e) {
			e.printStackTrace();

		}
		System.out.println("toHtml:"+toHtml("<a>ttt</a>"));
		System.out.println("Htmlto:"+htmlTo("&lt;a&gt;ttt&lt;/a&gt;"));
		// System.out.println(encodeConvert(encodeConvert("a中华人民共和国b","utf-8","gbk"),"gbk","utf-8"));
		System.exit(0);

	}
}
